﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Common;
using DogCheck;
using Equipment;
using Model;
using ActUtlType64Lib;
using DAL;
using MySql.Data.MySqlClient;
using System.Linq.Expressions;
using System.Xml.Linq;

namespace OliveAirLeakTest
{
    public partial class MainFrm : Form
    {
        SerialPort serialPort;
        SerialPort myPort;
        Product myProduct;
        SynchronizationContext synchronizationContext;
        ActUtlType64 myPlc = new ActUtlType64();
        int lastScanCompleted;
        int lastTesting;
        string ScanCompeletedAddr = null;
        string TestingAddr = null;
        System.Threading.Timer timer = null;
        bool testFlag = false;
        Recode currentRecord = null;
        string resultString = string.Empty;
        public MainFrm()
        {
            InitializeComponent();
            synchronizationContext = SynchronizationContext.Current;
            serialPort = new SerialPort();
            myPort = new SerialPort();
            myProduct = new Product();
            myPlc.ActLogicalStationNumber = 1;
            myPlc.ActPassword = "";
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort.PortName = ConfigHelper.ReadIni("SystemSettings", "ScanCom", "COM1", 255);
            serialPort.BaudRate = 9600;
            serialPort.Parity = Parity.None;
            serialPort.DataBits = 8;
            serialPort.StopBits = StopBits.One;
            serialPort.DataReceived += SerialPort_DataReceived;

            myPort.PortName = ConfigHelper.ReadIni("SystemSettings", "ATEQCom", "COM2", 255);
            myPort.BaudRate = 9600;
            myPort.Parity = Parity.None;
            myPort.DataBits = 8;
            myPort.StopBits = StopBits.One;
            myPort.DataReceived += MyPort_DataReceived;

            ScanCompeletedAddr = ConfigHelper.ReadIni("SystemSettings", "PLCAddrScanCompeleted", "M100",255);
            TestingAddr = ConfigHelper.ReadIni("SystemSettings", "PLCAddrTesting", "M500", 255);

            string name = ConfigHelper.ReadIni("SystemSettings", "Product", "", 255);
            cmbProduct.Text = name;
            btnChangeModel_Click(null, null);
            //myProduct.Id = Convert.ToInt32(ConfigHelper.ReadIni("SystemSettings", "CProduct", "1", 255));
            //SqlSugarHelper sqlSugarHelper = new SqlSugarHelper();
            //myProduct = sqlSugarHelper.QueryOne<Product>(myProduct.Id);
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                }
                serialPort.Open();
                serialPort.ReadExisting();
                AppLog.WriteLog(lvLog, $"扫码枪串口{serialPort.PortName}打开成功");
            }
            catch (Exception ex)
            {
                AppLog.WriteLog(lvLog,"串口打开失败："+ex.Message,2);
            }

            try
            {
                if (myPort.IsOpen)
                {
                    myPort.Close();
                }
                myPort.Open();
                myPort.ReadExisting();
                AppLog.WriteLog(lvLog, $"仪表串口{myPort.PortName}打开成功");
            }
            catch(Exception ex)
            {
                AppLog.WriteLog(lvLog,$"仪表串口{myPort.PortName}打开失败：{ex.Message}",2);
            }

            try
            {
                int iRet = myPlc.Open();
                if( iRet == 0)
                {
                    AppLog.WriteLog(lvLog, "PLC组件打开成功");
                }
                else
                {
                    AppLog.WriteLog(lvLog, "PLC组件打开失败");
                }
            }
            catch(Exception ex)
            {
                AppLog.WriteLog(lvLog, $"PLC组件打开时异常：{ex.Message}");
            }


            timer = new System.Threading.Timer(new TimerCallback(DoTime), null, 0, 100);
            AppLog.WriteLog(lvLog, "启动多线程计时器，轮询PLC状态");


            AppLog.WriteLog(lvLog, "********程序启动完成********",0);

            

        }

        private void MyPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(50);
            resultString = myPort.ReadExisting();
            AppLog.WriteLog(lvLog,$"收到仪表结果报文：{resultString}");
        }

        private void DoTime(object obj)
        {
            int ScanComplete;
            int iRet = myPlc.GetDevice(ScanCompeletedAddr, out ScanComplete);
            if( iRet == 0)
            {
                //AppLog.WriteLog(lvLog, $"扫码标志位读取成功，{ScanComplete.ToString()}");
                
                    if (ScanComplete == 1 &&lastScanCompleted==0)
                    {
                        //扫码按钮变绿
                        synchronizationContext.Post(btnScanCompleteChangeColor, Color.Green);
                        AppLog.WriteLog(lvLog, "收到扫码完成置位信号");
                    }
                    else if(ScanComplete ==0 && lastScanCompleted ==1)
                    {
                        //扫码按钮变白
                        synchronizationContext.Post(btnScanCompleteChangeColor, SystemColors.Control);
                        AppLog.WriteLog(lvLog, "收到扫码完成复位信号");

                    }
                    lastScanCompleted = ScanComplete;
                
            }
            else
            {
                AppLog.WriteLog(lvLog, $"扫码标志位读取失败，错误码：{iRet.ToString()}",2);
            }
            int Testing;
            int iRet2 = myPlc.GetDevice(TestingAddr, out Testing);
            if (iRet2 == 0)
            {
                if(Testing==1 && lastTesting == 0)
                {
                    //上升沿，测试中按钮变绿，测试开始
                    synchronizationContext.Post(btnTestingChangeColor, Color.Green);
                    AppLog.WriteLog(lvLog, "检测到测试开始信号");
                    //扫码功能屏蔽时，不响应
                    if (testFlag )
                    {
                      
                        TestBegin();
                    }
                        
                }
                else if(Testing==0 && lastTesting == 1)
                {

                    //下降沿，测试中按钮变白,测试结束
                    synchronizationContext.Post(btnTestingChangeColor, SystemColors.Control);

                    AppLog.WriteLog(lvLog, "检测到测试结束信号");
                    //扫码功能屏蔽时，不响应
                    if(testFlag)
                        TestEnd();
                }
                lastTesting = Testing;
            }
            else
            {
                AppLog.WriteLog(lvLog, $"测试标志位读取失败，错误码：{iRet.ToString()}", 2);
            }
        }

        private void TestEnd()
        {
            Task.Factory.StartNew(() =>
            {
                //防止仪表结果发送延迟
                Thread.Sleep(300);
                currentRecord.TestTime = DateTime.Now;
                if(resultString == null ||resultString == string.Empty)
                {
                    AppLog.WriteLog(lvLog, $"测试结束，未收到仪表结果报文");
                }
                else
                {
                    try
                    {
                        string[] strs = resultString.Split(':');
                        currentRecord.TestNo = strs[0];
                        currentRecord.TestPressure = strs[1];
                        currentRecord.TestRstr = strs[2];
                        currentRecord.TestResult = strs[3];
                        AppLog.WriteLog(lvLog, "气密数据解析成功");

                        AteqResultPrint(lvResult, currentRecord);
                        SqlSugarHelper sqlSugarHelper = new SqlSugarHelper();
                        sqlSugarHelper.Insert<Recode>(currentRecord);
                        AppLog.WriteLog(lvLog, "数据库保存成功");

                        synchronizationContext.Post(tbCodeStrChange, "");
                        AppLog.WriteLog(lvLog, "二维码清空");
                        testFlag = false;

                    }
                    catch (Exception ex)
                    {
                        AppLog.WriteLog(lvLog, $"气密数据解析失败：{ex.Message}");
                    }
                   
                }
            });
        }

        private void TestBegin()
        {
            Task.Factory.StartNew(() =>
            {
               
                currentRecord = new Recode();
                currentRecord.ProductName = myProduct.Name;
                currentRecord.Code = tbCodeStr.Text;

                //清空仪表接收串口的缓存
                myPort.ReadExisting();
               // AppLog.WriteLog(lvLog, "气密测试开始");
            });
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            System.Threading.Thread.Sleep(50);
            string str = serialPort.ReadExisting();
            AppLog.WriteLog(lvLog, $"串口收到码文内容：{str}");
            if (btnTesting.BackColor == Color.Green)
            {
                //测试开始后，对扫码不再进行响应
                
                AppLog.WriteLog(lvLog, $"测试期间收到二维码：{str}");
            }
            else
            {
                if (str.Contains('\r'))    ///二维码结束符换行符
                {

                    str = str.Substring(0,str.IndexOf('\r'));
                    if (myProduct.Check(str))         //二维码符合特征要求
                    {
                        //二维码鉴定完成
                        synchronizationContext.Post(tbCodeStrChange, str);

                        //进行扫码完成置位
                        int iRet =myPlc.SetDevice(ScanCompeletedAddr,1);
                        if( iRet == 0)
                        {
                            AppLog.WriteLog(lvLog, $"扫码完成后，对PLC地址{ScanCompeletedAddr}置位成功");
                            testFlag = true;
                        }
                        else
                        {
                            AppLog.WriteLog(lvLog, $"扫码完成后，对PLC地址{ScanCompeletedAddr}置位失败，错误码{iRet.ToString("X")}");
                        }
                    }
                    else
                    {
                        AppLog.WriteLog(lvLog, $"判断码文不符合当前产品规则：{str}");
                    }
                }
                else
                {
                    AppLog.WriteLog(lvLog, $"码文没有包含合法的结束符");
                }
                
            }
        }
        private void tbCodeStrChange(object obj)
        {
            this.tbCodeStr.Text = (string)obj;
        }

        private void btnScanCompleteChangeColor(object obj)
        {
            this.btnScanCompeleted.BackColor = (Color)obj;
        }
        private void btnTestingChangeColor(object obj)
        {
            this.btnTesting.BackColor = (Color)obj; 
        }

        private void btnChangeModel_Click(object sender, EventArgs e)
        {
            SqlSugarHelper sqlSugarHelper = new SqlSugarHelper();
            Expression<Func<Product, bool>> exp = it => it.Name == cmbProduct.Text;
            myProduct = sqlSugarHelper.QueryOne(exp);
            
            if (myProduct == null)
            {
                string msg = "产品名称载入有错误";
                MessageBox.Show(msg);
                AppLog.WriteLog(lvLog, msg);
            }
            else
            {
                ConfigHelper.WriteIni("SystemSettings", "Product", cmbProduct.Text);
                tbProductName.Text = myProduct.Name;
                tbLength.Text = myProduct.Length.ToString();
                tbCharacterCode.Text = myProduct.CharacterCode;
                tbCCodeLocation.Text = myProduct.CCodeLocation.ToString();
                tbCCodeLength.Text = myProduct.CCodeLength.ToString();
                AppLog.WriteLog(lvLog, "产品载入成功");
            }
            //DogFeature df = new DogFeature(18932);
            //Dog = new Dog(df);

            //DogStatus status = Dog.Login(VendorCode.Code);
            //MessageBox.Show(status.ToString());
            //DateTime dt = new DateTime();
            //Dog.GetTime(ref dt);

            //MessageBox.Show(dt.ToString());
            //DateTime dateTime = new DateTime(2023,12,2,0,0,0);
            //if (dateTime > dt)
            //{
            //    MessageBox.Show("允许使用");
            //}
            //else
            //{
            //    MessageBox.Show("授权已超期");
            //}
            //Dog.Logout();
            // MessageBox.Show(SqlSugarHelper.Db.GetHashCode().ToString());


        }


        private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("确定要退出测试系统？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                this.Dispose();
                Application.Exit();
            }
            else
            {
                //不关闭
                e.Cancel = true;
            }
        }

        private void MainFrm_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                int iRet = myPlc.Close();
                if (iRet == 0)
                {
                    AppLog.WriteLog(lvLog, "PLC组件关闭成功");
                }
                else
                {
                    AppLog.WriteLog(lvLog, "PLC组件关闭失败");
                }
            }
            catch(Exception ex)
            {
                AppLog.WriteLog(lvLog, $"关闭PLC组件时遇到错误：{ex.Message}");
            }
            myPort.Close();
            serialPort.Close();

            AppLog.WriteLog(lvLog, "========程序关闭========");
        }

        private void 设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form form= new SettingFrm();
            form.ShowDialog();
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void comboBox1_DropDown(object sender, EventArgs e)
        {
            cmbProduct.Items.Clear();
            SqlSugarHelper sqlSugarHelper = new SqlSugarHelper();
            List<Product> products = sqlSugarHelper.QueryAll<Product>();
            foreach (Product product in products)
            {
                cmbProduct.Items.Add(product.Name);
            }
        }

        private void 数据查询ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form queryFrm = new QueryFrm(); 
            queryFrm.ShowDialog();
        }


        private void AteqResultPrint(ListView listView, Recode recode)
        {
            ListViewItem listViewItem = new ListViewItem(recode.TestTime.ToString("yyyy-MM-dd  HH:mm:ss"));
            listViewItem.SubItems.Add(recode.ProductName);
            listViewItem.SubItems.Add(recode.Code);
            listViewItem.SubItems.Add(recode.TestNo);
            listViewItem.SubItems.Add(recode.TestPressure);
            listViewItem.SubItems.Add(recode.TestRstr);
            listViewItem.SubItems.Add(recode.TestResult);

            if (listView.InvokeRequired)
            {
                listView.Invoke(new Action(() =>
                {
                    listView.Items.Insert(0, listViewItem);
                    if (listView.Items.Count >= 20)
                    {
                        listView.Items.RemoveAt(listView.Items.Count - 1);
                    }

                }));
            }
            else
            {
                listView.Items.Insert(0, listViewItem);
                if (listView.Items.Count >= 20)
                {
                    listView.Items.RemoveAt(listView.Items.Count - 1);
                }
            }
        }
    }

}
